﻿using System;
using System.Collections.Generic;
using System.Drawing;
using OpenShape;

namespace VectorAnalys
{
    class VectorAnalysis
    {
        public List<SelectFeatureID> func_SelectPolygonToPoint(PointF selPoint, int pIndex, Scaler m_scaler)
        {
            //=========


            List<SelectFeatureID> pSelectFeatureID = new List<SelectFeatureID>();

            double sx, sy;
            int eIndex;

            if (pIndex == -1)
            {
                pIndex = 0;
                eIndex = LayerManager.m_Layers.Count;
            }
            else
            {
                eIndex = pIndex + 1;
            }

            Layer pLayer = LayerManager.m_Layers[pIndex];

            for (int Index = pIndex; Index < eIndex ; Index++)
            {

                int m_nRecords = pLayer.m_nRecords;

                for (int i = 0; i < m_nRecords; i++)
                {

                    GeoPolygon m_SO = (GeoPolygon)pLayer.m_SpatialObject[i];


                    int NumPoints = m_SO.NumPoints;
                    int NumParts = m_SO.NumParts;
                    PointF[] pTempPoint = new PointF[NumPoints];
                    int[] pVertex = new int[NumParts];


                    // 한개 feature의 점을 pTempPoint에 저장

                    for (int j = 0; j < NumPoints; j++)
                    {

                        m_scaler.WorldToDevice(m_SO.Points[j].X, m_SO.Points[j].Y, out sx, out sy);
                        pTempPoint[j].X = (float)sx;
                        pTempPoint[j].Y = (float)sy;

                    }

                    for (int j = 0; j < NumParts; j++)
                    {

                        if (j == NumParts - 1)
                        {
                            pVertex[j] = NumPoints - m_SO.Parts[j];
                            PointF[] pTempPartPoint = new PointF[pVertex[j]];
                            for (int k = m_SO.Parts[j]; k < NumPoints; k++)
                            {
                                pTempPartPoint[k - m_SO.Parts[j]] = pTempPoint[k];
                            }
                            int polyside = pTempPartPoint.Length - 1;

                            bool oddNodes = false;

                            int n = polyside - 1;

                            for (int m = 0; m < polyside; m++)
                            {
                                if (pTempPartPoint[m].Y < selPoint.Y && pTempPartPoint[n].Y >= selPoint.Y || pTempPartPoint[n].Y < selPoint.Y && pTempPartPoint[m].Y >= selPoint.Y)
                                {
                                    if (pTempPartPoint[m].X + (selPoint.Y - pTempPartPoint[m].Y) / (pTempPartPoint[n].Y - pTempPartPoint[m].Y) * (pTempPartPoint[n].X - pTempPartPoint[m].X) < selPoint.X)
                                    {
                                        oddNodes = !oddNodes;
                                    }
                                }
                                n = m;
                            }//for m



                            if (oddNodes)
                            {
                                pSelectFeatureID.Add(new SelectFeatureID(Index, i));
                            }
                        }
                        else
                        {
                            pVertex[j] = m_SO.Parts[j + 1] - m_SO.Parts[j];
                            PointF[] pTempPartPoint = new PointF[pVertex[j]];
                            for (int k = m_SO.Parts[j]; k < m_SO.Parts[j + 1]; k++)
                            {
                                pTempPartPoint[k - m_SO.Parts[j]] = pTempPoint[k];
                            }

                            int polyside = pTempPartPoint.Length - 1;

                            bool oddNodes = false;

                            int n = polyside - 1;

                            for (int m = 0; m < polyside; m++)
                            {
                                if (pTempPartPoint[m].Y < selPoint.Y && pTempPartPoint[n].Y >= selPoint.Y || pTempPartPoint[n].Y < selPoint.Y && pTempPartPoint[m].Y >= selPoint.Y)
                                {
                                    if (pTempPartPoint[m].X + (selPoint.Y - pTempPartPoint[m].Y) / (pTempPartPoint[n].Y - pTempPartPoint[m].Y) * (pTempPartPoint[n].X - pTempPartPoint[m].X) < selPoint.X)
                                    {
                                        oddNodes = !oddNodes;
                                    }
                                }
                                n = m;
                            }//for m

                            if (oddNodes)
                            {
                                pSelectFeatureID.Add(new SelectFeatureID (Index , i));
                            }

                        }
                    }
                }
            }
            //========
            return pSelectFeatureID;
        }

        public double[] Cal_Geometry(PointF[] Cal_Point)  // 도형별 면적[0], 둘레[1], 중심점X[2], 중심점Y[3] 계산, 단위는 Double
        {
            double[] cal_ans = new double[4];

            int len = Cal_Point.Length;

            int j;

            double PartArea = 0;
            double PartCx = 0;
            double PartCy = 0;
            double PartCircumference = 0;
            double Area, Cx, Cy, Circumference;

            j = len - 1;

            for (int i = 0; i < len; i++)
            {
                double temp_cal;
                temp_cal = ((Cal_Point[i].X * Cal_Point[j].Y) - (Cal_Point[j].X * Cal_Point[i].Y));
                PartArea += temp_cal;
                PartCircumference += Math.Sqrt(Math.Pow(Cal_Point[i].X - Cal_Point[j].X, 2) + Math.Pow(Cal_Point[i].Y - Cal_Point[j].Y, 2));
                PartCx += (Cal_Point[i].X + Cal_Point[j].X) * temp_cal;
                PartCy += (Cal_Point[i].Y + Cal_Point[j].Y) * temp_cal;
                j = i;
            }
            Area = PartArea / 2;
            cal_ans[0] = Math.Abs(Area);
            cal_ans[1] = Circumference = PartCircumference;
            cal_ans[2] = Cx = PartCx / (6 * Area);
            cal_ans[3] = Cy = PartCy / (6 * Area);

            return cal_ans;
        }

    }
}
